package com.company.function;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * @author yingfing
 * @create 2020--09--27 20:58
 * @describe
 */
public class TestFunctionInterface {
    public static void main(String[] args) {
        // JUnit 4
        // @Test

        // 1. JDK 自带的常用函数式接口
        // Supplier T get();    无参数,有返回值
        // Consumer void accept(T t);   有参数,无返回值
        // Function R apply(T t);   有参数,有返回值
        // Predicate boolean test (T t);    有参数,返回值 boolean 断言接口
        Supplier<Integer> supplier = new Supplier<Integer>() { // ()->T
            @Override
            public Integer get() {
                return new Integer(1);
            }
        };

        System.out.println(supplier.get());

        Consumer<Integer> consumer = new Consumer<Integer>() { // x->{}
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        };

        consumer.accept(100);

        Function<Integer, String> function = new Function<Integer, String>() { // x-> y
            @Override
            public String apply(Integer integer) {
                return integer + "";
            }
        };

        String apply = function.apply(100);

        Predicate<Integer> predicate = new Predicate<Integer>() { // T-> boolean
            @Override
            public boolean test(Integer integer) {
                return integer > 20;
            }
        };

        boolean test = predicate.test(25);

        // 演示函数式接口的使用
        List<Employee> employees = Arrays.asList(
                new Employee("z3", 22, 5600.00),
                new Employee("li4", 21, 5500.00),
                new Employee("wang5", 23, 5400.00),
                new Employee("zhao6", 20, 5300.00)
        );

        List<Employee> employeesBySalary = getEmployeeBySalary(employees, 5000.00);
        List<Employee> emplyeeByAge = getEmployeeBtAge(employees, 20);

//        List<Employee> employeeByAge = getEmployeesByPredicate(employees, new Predicate<Employee>() {
//            @Override
//            public boolean test(Employee employee) {
//                return employee.getSalary() > 500;
//            }
//        });

        List<Employee> employeesByPredicate = getEmployeesByPredicate(employees, e -> e.getAge() > 20);
        List<Employee> employeesByPredicate1 = getEmployeesByPredicate(employees, e -> e.getSalary() > 5000.00);

        List<Employee> result = new ArrayList<>();
        List employeesByPredicate2 = getEmployeesByPredicate(list -> {
            List<Employee> es = new ArrayList<>();
            for (Object e : list) {
                if (((Employee) e).getSalary() > 5000) {
                    es.add(((Employee) e));
                }
            }
            return es;
        }, employees);

        Function<List, List> function1 = list -> {
            List<Employee> es = new ArrayList<>();
            for (Object e : list) {
                es.add(((Employee) e));
            }
            return es;
        };
        List apply1 = function1.apply(employees);


        // 泛型补充
        // function <? super V,? extends T> before
        // ? super V V的父类型
        // ? extends T 传的参数类型需要是 T 的子类型

    }

    public static String Integer2Str(Integer i) {
        return i + "";
    }

    public static boolean getByNum(int num) {
        return num > 20;
    }

    public static List<Employee> getEmployeeBySalary(List<Employee> list, double salary) {
        ArrayList<Employee> employees = new ArrayList<>();
        for (Employee e : list) {
            if (e.getSalary() > salary) {
                employees.add(e);
            }
        }
        return employees;
    }

    public static List<Employee> getEmployeeBtAge(List<Employee> list, int age) {
        ArrayList<Employee> employees = new ArrayList<>();
        for (Employee e : list) {
            if (e.getAge() > age) {
                employees.add(e);
            }
        }
        return employees;
    }

    public static List<Employee> getEmployeesByPredicate(List<Employee> list, Predicate<Employee> predicate) {
        ArrayList<Employee> employees = new ArrayList<>();
        for (Employee e : list) {
            if (predicate.test(e)) {
                // 使用的是断言
                employees.add(e);
            }
        }
        return employees;
    }

    public static List getEmployeesByPredicate(Function<List, List> function, List apply) {
        return function.apply(apply);
    }
}


class Employee {
    String name;
    int age;
    double salary;

    public Employee(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

// 2. 自带的常用函数式接口有子类
// 3. 自定义函数式接口